﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="AdminController.cs" company="DissingNellemann">
//   All rights reserved
// </copyright>
// <summary>
//   The admin controller.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Website.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.Mvc;
    using System.Web.Security;
    using Website.CRUDServices;
    using Website.Models;
    using Website.Models.Styling;
    using Website.Models.ViewModels;
    using User = Website.Models.Domain.User;

    /// <summary>
    ///     The admin controller.
    /// </summary>
    [Authorize(Roles = "Admin")]
    public class AdminController : BaseController
    {
        // GET: /Admin/
        #region Public Methods and Operators

        /// <summary>
        /// The edit user.
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <returns>
        /// The <see cref="ActionResult"/>.
        /// </returns>
        public ActionResult EditUser(Guid id)
        {
            this.Session["CurrentSubMenuSelection"] = "UserView";
            var user = new User();

            

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var query = new UsersQuery { Settings = new SearchSettings { IDEquals = id } };
                    var res = (UsersResult)client.Query(query);
                    if (res.List.Any())
                    {
                        if (res.List[0] != null)
                        {
                            user = Models.Domain.User.Convert(res.List[0]);
                        }
                    }
                    
                });

            return View(user);
        }

        /// <summary>
        /// The edit user.
        /// </summary>
        /// <param name="updatedUser">
        /// The updated user.
        /// </param>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <returns>
        /// The <see cref="ActionResult"/>.
        /// </returns>
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EditUser(UserEdited updatedUser, Guid id)
        {
            if (!this.ModelState.IsValid)
            {
                this.ViewData["ErrorMessage"] = "Der opstod en fejl. Prøv venligst igen.";
                return this.EditUser(id);
            }

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var cmd = new UpdateUserCommand();
                    var dto = new CRUDServices.User
                    {
                        Name = updatedUser.Name,
                        Username = updatedUser.Username,
                        ID = id,
                        PhoneNumber = updatedUser.PhoneNumber,
                        Email = updatedUser.Email
                    };
                    if (!string.IsNullOrWhiteSpace(updatedUser.Password)
                        && (updatedUser.Password == updatedUser.Password2))
                    {
                        var cmdU = new UpdateUserPasswordCommand { ID = id, NewPassword = MD5Encrypter.EncryptPassword(id.ToString(), updatedUser.Password) };
                        client.ExecuteCommand(cmdU);
                    }

                    cmd.UpdatedUser = dto;
                    client.ExecuteCommand(cmd);
                });
            return this.RedirectToAction("Index");
        }

        /// <summary>
        ///     The index.
        /// </summary>
        /// <returns>
        ///     The <see cref="ActionResult" />.
        /// </returns>
        public ActionResult Index()
        {
            this.Init("Admin");

            var submenuItems = new List<MenuItem>();
            var item = new MenuItem
            {
                ActionName = "UserView",
                ControllerName = "Admin",
                CurrentMenuSelectionName = "UserView",
                ImageName = "user",
                Title = "Bruger Oversigt"
            };
            submenuItems.Add(item);

            var item2 = new MenuItem
            {
                ActionName = "NewUser",
                ControllerName = "Admin",
                CurrentMenuSelectionName = "NewUser",
                ImageName = "config",
                Title = "Ny Bruger"
            };
            submenuItems.Add(item2);

            var item3 = new MenuItem
            {
                ActionName = "LogSearch",
                ControllerName = "Admin",
                CurrentMenuSelectionName = "LogSearch",
                ImageName = "search",
                Title = "Log"
            };
            submenuItems.Add(item3);

            this.Session["SubMenuItems"] = submenuItems;
            return RedirectToAction("UserView");
        }

        /// <summary>
        ///     The new user.
        /// </summary>
        /// <returns>
        ///     The <see cref="ActionResult" />.
        /// </returns>
        public ActionResult NewUser()
        {
            this.Session["CurrentSubMenuSelection"] = "NewUser";
            return this.View();
        }

        /// <summary>
        /// The posted page for new user.
        /// </summary>
        /// <param name="newUser">
        /// The new user.
        /// </param>
        /// <returns>
        /// The <see cref="ActionResult"/>.
        /// </returns>
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult NewUser(User newUser)
        {
            this.Session["CurrentSubMenuSelection"] = "NewUser";

            if (!this.ModelState.IsValid)
            {
                return this.View();
            }

            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var cmd = new CreateUserCommand();
                    var dto = new CRUDServices.User
                    {
                        ID = Guid.NewGuid(),
                        Name = newUser.Name,
                        Username = newUser.Username,
                        PhoneNumber = newUser.PhoneNumber,
                        Email = newUser.Email
                    };
                    cmd.EncryptedPassword = MD5Encrypter.EncryptPassword(dto.ID.ToString(), newUser.Password);
                    cmd.User = dto;
                    client.ExecuteCommand(cmd);
                    if (!Roles.IsUserInRole(dto.ID.ToString(), "User"))
                    {
                        Roles.AddUserToRole(dto.ID.ToString(), "User");
                    }
                });
            return this.RedirectToAction("Index");
        }

        /// <summary>
        /// The user view.
        /// </summary>
        /// <param name="skip">
        /// The skip.
        /// </param>
        /// <param name="take">
        /// The take.
        /// </param>
        /// <param name="orderBy">
        /// The order by.
        /// </param>
        /// <param name="sortAscending">
        /// The sort ascending.
        /// </param>
        /// <returns>
        /// The <see cref="ActionResult"/>.
        /// </returns>
        public ActionResult UserView(int? skip, int? take, string orderBy, bool? sortAscending)
        {
            this.Session["CurrentSubMenuSelection"] = "UserView";

            // vars
            var userList = new AdminUserView
            {
                Skip = skip != null ? (int)skip : 0,
                Take = take != null ? (int)take : 20
            };
            orderBy = orderBy ?? "Name";

            // header items for the table
            var headerItems = new List<TableViewHeaderItem>();
            var item1 = new TableViewHeaderItem { Text = "Navn", SortableName = "Name", IsSortable = true };
            var item2 = new TableViewHeaderItem { Text = "Brugernavn", SortableName = "Username", IsSortable = true };
            var item3 = new TableViewHeaderItem { Text = "E-mail", SortableName = "Email", IsSortable = true };
            var item4 = new TableViewHeaderItem { Text = "Telefon", SortableName = "PhoneNumber", IsSortable = true };
            headerItems.Add(item1);
            headerItems.Add(item2);
            headerItems.Add(item3);
            headerItems.Add(item4);

            userList.TableHeader = TableViewHeader.GetTableHeader(
                "UserView", 20, orderBy, headerItems, sortAscending == null || (bool)sortAscending);

            // Create client
            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    // Create query of correct type
                    var query = new UsersQuery
                    {
                        OnlyActiveUsers = true,
                        Settings =
                            new SearchSettings
                            {
                                OrderBy = orderBy,
                                Skip = skip,
                                Take = take,
                                SortAscending = sortAscending ?? true
                            }
                    };

                    // Retrieve the resultset
                    var res = (UsersResult)client.Query(query);

                    // Get the list from the resultset
                    userList.TotalUsers = res.TotalRowCount;
                    userList.UserList = res.List.ToList();
                    userList.SortAscending = sortAscending ?? true;
                });

            return View(userList);
        }

        public ActionResult LogSearch()
        {
            this.Session["CurrentSubMenuSelection"] = "LogSearch";
            this.ViewData["Users"] = PrimitiveTypes.GetUsersWithIDs(new List<Guid>());
            return View();
        }

        public ActionResult LogSearchResult(Guid? User, DateTime? HappenedAfter, DateTime? HappenedBefore)
        {
            this.ViewData["UserID"] = User;
            this.ViewData["After"] = HappenedAfter;
            this.ViewData["Before"] = HappenedBefore;
            LogView view = PrimitiveTypes.GetLogViewForUser(User, HappenedAfter, HappenedBefore);

            return View(view);            
        }

        public ActionResult DeactivateUser(Guid? id)
        {
            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    var cmd = new DeactivateUserCommand(){
                         ID = id.Value
                    };

                    client.ExecuteCommand(cmd);
                });

            return RedirectToAction("UserView");
        }   

        #endregion
    }
}